/*
 * 能发送异步ajax请求的函数模块
 * 封装axios库
 * 函数的返回值是promise对象
 *
 * 1、优化：统一处理请求异常。
 *       在外层包一个Promise对象
 *       请求出错不用reject，使用错误提示。
 * */

import { BaseUrl, ReqType } from "./config";
import axios from "axios";
import { message } from "antd";
import { getApp } from "../utils";
import { hasLoginCloud } from "./customLogin";
import { userOptions } from "../utils/storageUtils";
import { reqLogin } from "./index";

/**
 * 将/manage/category/list转化为云开发能够识别的形势。
 * @param name
 * @param data
 */
const formatName = (name, data) => {
  /**
   * 如果是'/manage/category/list'，会变成
   * [ '', 'manage', 'category', 'list' ]
   */
  const list = name.split("/");
  const resultData = {
    name: list[1],
    data: {
      $url: name.replace(`/${list[1]}`, ""),
      other: { ...data },
    },
  };

  return {
    ...resultData,
  };
};

/**
 * 注意，如果长时间不登录，那么会出现错误
 * “Unhandled Rejection (Error): [tcb-js-sdk] 未登录CloudBase”
 * 解决方法是：
 * 运行 actions.js 中的方法：logout()。
 * 删除 userOption 中的user信息，让程序跳转到 login 页面。
 *
 * @param name
 * @param data
 * @param type
 * @return {Promise<*|void>}
 */
export const ajaxTcbCloud = async (name, data = {}, type = ReqType.GET) => {
  // 如果没有登录云平台
  const loginState = await hasLoginCloud();
  if (!loginState) {
    const userInfo = userOptions.getUser();
    if (null !== userInfo) {
      const { username, password } = userInfo.data;
      try {
        /**
         * 这里要注明是否对密码进行md5加密。
         * 默认是"不加密"
         * 那么其实这里的密码是从 userOptions 中获取的，已经加密过了。
         * 再次加密那么密码就错误了。
         */
        await reqLogin(username, password);
      } catch (e) {
        console.error(e);
      }
    }
  }

  const app = getApp();
  const dataObj = formatName(name, data);

  return new Promise((resolve, reject) => {
    app
      .callFunction(dataObj)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
};

export function ajax(url, data = {}, type = ReqType.GET) {
  url = BaseUrl + url;

  return new Promise((resolve, reject) => {
    // 1、执行ajax请求
    let promise;

    switch (type) {
      case ReqType.GET:
        promise = axios.get(url, { params: data });
        break;
      case ReqType.POST:
        promise = axios.post(url, data);
        break;
      case ReqType.PUT:
        promise = axios.put(url, data);
        break;
      default:
        break;
    }

    // 2、成功就resolve
    // 3、 失败，不调用reject（如果调用，那么外面就会执行catch中的错误处理），显示异常信息。
    promise
      .then((response) => resolve(response))
      .catch((err) => message.error("错误信息:" + err.message));
  });
}
